#include "ets_sys.h"
#include "driver/uart.h"
#include "osapi.h"
#include "config.h"
#include "debug.h"
#include "gpio.h"
#include "user_interface.h"
#include "mem.h"
#include "user_config.h"


/******************************************************************************
 * FunctionName : user_set_softap_config
 * Description  : set SSID and password of ESP8266 softAP
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
uint16_t ICACHE_FLASH_ATTR
fwProCRC(uint8_t *data_to_cal,uint8_t data_len)
{
	int i=0;
	uint16_t crc_value=0xffff;
	while(data_len--)
	{
	  crc_value^=*data_to_cal++;
    for(i=0;i<8;i++)
		{
		  if(crc_value&0x0001) crc_value=(crc_value>>1)^0xa001;
		  else crc_value=crc_value>>1;
		}
	}
	return (crc_value);
}
/******************************************************************************
 * FunctionName : user_set_softap_config
 * Description  : set SSID and password of ESP8266 softAP
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
uint8_t ICACHE_FLASH_ATTR
dtProCRC(uint8_t * pro_buff)
{
	int i;
	uint8_t crc_tmp=0;
	for(i=0;i<pro_buff[1]-1;i++)
	{
		crc_tmp+=pro_buff[i];
	}
	crc_tmp=~crc_tmp;
	crc_tmp+=1;
	return crc_tmp;
}
/******************************************************************************
 * FunctionName : user_set_softap_config
 * Description  : set SSID and password of ESP8266 softAP
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
int ICACHE_FLASH_ATTR
fwSendData(uint8_t *data_buff,uint16_t cmd,uint16_t data_len,uint16_t version)
{
	int i=0;

	uint8_t *send_buff = (uint8_t*)os_zalloc(255);
    if(send_buff==NULL) return -1;

	send_buff[0]=0xaa;
	send_buff[1]=0x55;
	send_buff[2]=0xaa;
	send_buff[3]=0x55;
	send_buff[4]=data_len>>8;
	send_buff[5]=data_len>>0;
	send_buff[6]=cmd>>8;
	send_buff[7]=cmd>>0;
	send_buff[10]=version>>8;
	send_buff[11]=version>>0;

	for(i=0;i<data_len;i++) send_buff[12+i]=data_buff[i];

	uint16_t bl_crc=fwProCRC(data_buff,data_len);

	send_buff[8]=bl_crc>>8;
	send_buff[9]=bl_crc>>0;

	uart0_tx_buffer(send_buff,12+data_len);
	for(i=0;i<100;i++)
	{
		os_delay_us(1000);
		system_soft_wdt_feed();
	}
	os_free(send_buff);
}
/******************************************************************************
 * FunctionName : user_set_softap_config
 * Description  : set SSID and password of ESP8266 softAP
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
int ICACHE_FLASH_ATTR
dtSendData(uint16_t pack_decs,uint16_t msg_type,uint8_t* msg,uint8_t msg_len)
{
	int i=0;
	uint8_t *send_buff = (uint8_t*)os_zalloc(255);
    if(send_buff==NULL) return -1;

    send_buff[0]=0xaa;
    send_buff[1]=0x11+msg_len;
    send_buff[2]=pack_decs>>8;
    send_buff[3]=pack_decs>>0;
	for(i=0;i<8;i++)  send_buff[i+4]=0;
	send_buff[12]=msg_type>>8;
	send_buff[13]=msg_type>>0;
	for(i=0;i<2;i++)  send_buff[i+14]=0;
	if(msg!=NULL)
	{
		for(i=0;i<msg_len;i++) send_buff[i+16]=msg[i];
	}
	send_buff[send_buff[1]-1]=dtProCRC(send_buff);

	uart0_tx_buffer(send_buff,send_buff[1]);

	for(i=0;i<100;i++)
	{
		os_delay_us(1000);
		system_soft_wdt_feed();
	}

	os_free(send_buff);
}
/******************************************************************************
 * FunctionName : user_set_softap_config
 * Description  : set SSID and password of ESP8266 softAP
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
int ICACHE_FLASH_ATTR
olfinitySendData(uint8_t *data_buff,uint16_t cmd,uint16_t data_len)
{
	int i=0;

	uint8_t *send_buff = (uint8_t*)os_zalloc(255);
    if(send_buff==NULL) return -1;

	send_buff[0]=0x55;
	send_buff[1]=data_len;
	send_buff[2]=0xe1;
	send_buff[3]=0x00;
	for(i=0;i<data_len;i++) send_buff[4+i]=data_buff[i];

	uint16_t bl_crc=fwProCRC(send_buff+1,data_len+3);

	send_buff[send_buff[1]+4] =  bl_crc>>8;
	send_buff[send_buff[1]+5] =  bl_crc>>0;
	send_buff[send_buff[1]+6] =  0xee;

	uart0_tx_buffer(send_buff,12+data_len);

	for(i=0;i<100;i++)
	{
		os_delay_us(1000);
		system_soft_wdt_feed();
	}
	os_free(send_buff);
}
void ICACHE_FLASH_ATTR
heartbeat_send(uint8_t * mac,uint8_t net_state)
{
	uint8_t data[7]={0};
	data[0]=net_state;
	os_memcpy(data+1,mac,6);
	#if defined(_DT_PROTOCOL)
		dtSendData(0x1000,0x1115,data,sizeof data);
	#elif defined(_FW_PROTOCOL)
		fwSendData(data,0x000f,sizeof data,0x0000);
	#elif defined(_ALI_PROTOCOL)

	#elif defined(_OLFINITY_PROTOCOL)

		olfinitySendData(data,0xe1,sizeof data);

	#endif
}

int ICACHE_FLASH_ATTR
cmd_recv_parse(uint8_t * data)
{
	#if defined(_DT_PROTOCOL)
		if(data[0]==0xaa&&data[1]<250)
		{
			os_printf("dtProCRC(data)=%02x",dtProCRC(data));
			if(data[data[1]-1]==dtProCRC(data))
			{
				if(data[12]==0x20&&data[13]==0x01)
				{
					wifi_set_opmode(STATION_MODE);
					smartconfig_task();
					return 0;
				}
				if(data[12]==0x20&&data[13]==0x0a)
				{
					//get_upgrade_ip(domin_server);
					return 0;
				}
			}
		}
	#elif defined(_FW_PROTOCOL)
		uint16_t data_len_pro=0,data_crc_pro=0;
		char post_data[240]={0x00};
        if(data[0]==0xaa&&data[1]==0x55&&data[2]==0xaa&&data[3]==0x55)
		{
			data_len_pro =(uint16_t)data[4]*256+data[5];
			data_crc_pro =(uint16_t)data[8]*256+data[9];
			os_printf("------data_crc_pro=%02x\r\n",data_crc_pro);
			os_printf("------fwProCRC(data+12,data_len_pro)=%02x\r\n",fwProCRC(data+12,data_len_pro));
			if(data_crc_pro==fwProCRC(data+12,data_len_pro))
			{
			   if(data[6]==0x00&&data[7]==0x0a)
			   {
				   if(data[12]==0)
				   {
					   wifi_set_opmode(STATION_MODE);
					   smartconfig_task();
					   return 0;
				   }
			   }

			   else if(data[6]==0x00&&data[7]==0x02)
			   {
				   char temp_mqtt_mac[13];
				   uint8_t i=0;
				   for(i=0;i<12;i++)
				   {
					   temp_mqtt_mac[i]=mqtt_mac[i];
				   }
				   temp_mqtt_mac[12]='\0';
				   uint16_t hcho=(uint16_t)((uint16_t)data[12]*256+data[13]);
				   uint16_t tvoc=(uint16_t)((uint16_t)data[14]*256+data[15]);
				   uint16_t pm25=(uint16_t)data[16]*256+data[17];
				   uint8_t humi=data[18];
				   int16_t temp=((int16_t)(data[19]<<8)+data[20]);
				   uint16_t aqi =(uint16_t)data[21]+data[22];
				   uint16_t pm1 =(uint16_t)data[23]+data[24];
				   uint16_t pm10 =(uint16_t)data[25]+data[26];
				   uint16_t co2 =(uint16_t)data[27]+data[28];
				   uint8_t air =data[29];
				   uint8_t hcho_whole=hcho/1000;
				   uint16_t  hcho_decimal=hcho%1000;
				   uint8_t tvoc_whole=tvoc/1000;
				   	uint16_t  tvoc_decimal=tvoc%1000;
				   	uint8_t  temp_whole=temp/10;
				   	uint16_t temp_decimal=temp%10;
				   	if(temp>=0)
				   	{
				   os_sprintf(post_data,"hcho=%1d.%03d&tvoc=%=%1d.%03d&pm25=%d&humi=%d&temp=%02d.%01d&aqi=%d&pm1=%d&pm10=%d&co2=%d&air=%d&mac_address=%s" \
						   ,hcho_whole,hcho_decimal,tvoc_whole,tvoc_decimal,pm25,humi,temp_whole,temp_decimal,aqi,pm1,pm10,co2,air,temp_mqtt_mac);
				   	}
				   	else
				   	{
				   		temp=-temp;
				   		temp_whole=temp/10;
				   		temp_decimal=temp%10;
				   	 os_sprintf(post_data,"hcho=%1d.%03d&tvoc=%=%1d.%03d&pm25=%d&humi=%d&temp=-%02d.%01d&aqi=%d&pm1=%d&pm10=%d&co2=%d&air=%d&mac_address=%s" \
				   							   ,hcho_whole,hcho_decimal,tvoc_whole,tvoc_decimal,pm25,humi,temp_whole,temp_decimal,aqi,pm1,pm10,co2,air,temp_mqtt_mac);
				   	}
				   os_printf("post_data=%s\n",post_data);
				   post_data_server(post_data);
			   }
			}
		}
	#elif defined(_ALI_PROTOCOL)

	#elif defined(_OLFINITY_PROTOCOL)
		uint16_t data_len_pro=0,data_crc_pro=0;
        if(data[0]==0x55&&data[1]<240&&data[data[1]+6]==0xee)
        {
        	//配网指令
        	if(data[2]==0xe0)
        	{
				data_len_pro =data[1]+3;
				data_crc_pro =(uint16_t)data[data[1]+4]*256+data[data[1]+5];
				if(data_crc_pro==fwProCRC(data+1,data_len_pro))
				{
				   if(data[4]==0)
				   {
					   wifi_set_opmode(STATION_MODE);
					   smartconfig_task();
					   return 0;
				   }
				}
        	}
        }
	#endif
    return -1;
}

